/// Created by Nazariy Jaworski Copyright (c) 2013
/// Bot program
///
/// botserver.h -
///  implements server role mode of the bot
///
/// To Do list:
///  - run server in separate process
///  ...
///
/// v 0.1        08.04.2013

#ifndef BOTSERVER_H
#define BOTSERVER_H

#include <QtNetwork/QTcpServer>
#include <QtNetwork/QUdpSocket>
#include <QProcess>

class RemoteBotInfo : public QObject
{
    Q_OBJECT

    public: QTcpSocket *remoteQTcpSocket;
    private: QList<RemoteBotInfo *>::Iterator myPosition;
    /// \todo put here some extra info

    /// Warning! 'RemoteBotInfo' uses 'parent' to contact with 'BotServer',
    /// so 'parent' should be equal to 'BotServer' where 'RemoteBotInfo'
    /// was created. Constructor automatically pushes 'RemoteBotInfo' into
    /// back of 'BotServer.BotClients'
    public: RemoteBotInfo(QTcpSocket *remoteQTcpSocket, QObject *parent = NULL);


    public: ~RemoteBotInfo(){}
    public: Q_SLOT void OnTcpSocketInput(); ///< Processing TCP input data
    public: Q_SLOT void OnTcpSocketError(QAbstractSocket::SocketError socketError);
    ///< Processing TCP errors
    public: Q_SLOT void OnTcpSocketDisconnected(); ///< Processing TCP disconnect event
};

class BotServer : public QObject
///< BotServer class - implements the server role mode of a Bot
{
    Q_OBJECT

    public: QUdpSocket *myQUdpServerInputSocket;
    public: QUdpSocket *myQUdpServerOutputSocket;

    public: QList<RemoteBotInfo *> BotClients;

    public: QString ShowClients();  ///< Return simple string about connected clients

    public: QTcpServer *myQTcpServer;       ///< For communications, if Bot is a BotServer

    private: bool isClientRegistered(const QHostAddress &address, const quint16 port);
    ///< Check is the Bot with that address already registered

    private: Q_SLOT void OnUdpServerSocketInput(); ///< Processing UDP input data

    private: Q_SLOT void OnUdpServerInputSocketError(QAbstractSocket::SocketError socketError);
    ///< Process network UDP errors

    private: Q_SLOT void OnUdpServerOutputSocketError(QAbstractSocket::SocketError socketError);
    ///< Process network UDP errors

    private: Q_SLOT void OnNewServerConnection(); ///< Processing new Bot connections

    private: Q_SLOT void OnAcceptError(QAbstractSocket::SocketError socketError);
    ///< Processing connection errors

    public: BotServer(QObject *parent = NULL); ///< Common constructor
    public: ~BotServer();   ///< Common destructor
};

#endif // BOTSERVER_H
